home *** CD-ROM | disk | FTP | other *** search
- /*
- * Xblockbuster should run on any X11 system (bw or color) - MSW
- *
- *****************************************************************************
- * Appearance ONLY shamelessly stolen from the real video game,
- * wonderfully written by someone somewhere (I haven't got the foggiest).
- *
- * Move mouse to move pallet and keep the ball on the stage.
- *
- * Stages are built from various building blocks, some of which are based on
- * recollection from analogous blocks in the video game, others, in particular
- * the interesting ones, are new.
- *
- * The stages can be defined from the ascii map codes using any text editor.
- * They must be numbered consecutively from 0 with the total number
- * (i.e., one more than the highest number) available in the file nb_stages.
- *
- * -- Eric Van Gestel (ericvg@cs.kuleuven.ac.be)
- */
-
- #include "xblockbuster.h"
- #include <dirent.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <signal.h>
-
- #include "icons/blockbuster.icon"
- #include "patchlevel.h"
-
- int timer_active=FALSE, /* has the user started the ball? */
- window_active=FALSE; /* is the pointer in the window? */
- int time_to_move = 0;
-
-
-
- void
- time_tick(sig)
- int sig;
- {
- static unsigned short event_count = 0;
-
- time_to_move = 1;
- #ifdef INTR_DRAW
- if (timer_active && window_active) {
- move_balls();
- XFlush(display);
- }
- #endif /*INTR_DRAW*/
- }
-
- setup_itimer()
- {
- struct sigaction catch, devnull;
- struct itimerval interval;
-
- /* Catch SIGALARM reliably */
- catch.sa_handler = time_tick;
- sigemptyset(&catch.sa_mask);
- sigaddset(&catch.sa_mask, SIGALRM);
- catch.sa_flags = 0;
- if (sigaction(SIGALRM, &catch, &devnull) < 0)
- perror("sigaction");
-
- /* ... then set the interval timer */
- interval.it_value.tv_sec = 0;
- interval.it_value.tv_usec = 10000;
- interval.it_interval = interval.it_value;
- if (setitimer(ITIMER_REAL, &interval, (struct itimerval *)NULL) < 0)
- perror("setitimer");
- }
-
- void event_handler()
- {
- XEvent e;
- int row,col,sleeptime;
- double old_pallet_y;
- char keystr[2],str[10];
-
- setup_itimer();
-
- draw_pallet();
- while (1) {
- #ifndef INTR_DRAW
- if (time_to_move && timer_active && window_active) {
- time_to_move = 0;
- move_balls();
- }
-
- // Now, let's wait for an event, or time to move the balls
- {
- int Xfd;
- fd_set fds;
-
- Xfd = ConnectionNumber(display);
- FD_ZERO(&fds);
- FD_SET(Xfd, &fds);
- select(Xfd+1, &fds, &fds, &fds, 0);
- }
-
- if (XPending(display))
- #endif /*!INTR_DRAW*/
- {
- /* Event handling (if any events need to be handled) - MSW */
- XNextEvent(display, &e);
- #ifdef INTR_DRAW
- sighold(SIGALRM);
- #endif /*INTR_DRAW*/
- switch (e.type) {
- case ButtonPress:
- switch (e.xbutton.button) {
- case Button3: /* right mouse button */
- /* Clear message area */
- XFillRectangle(display, win, gc_erase,
- 0,0,STAGE_WIDTH_IN_PIXELS, MSG_HEIGHT);
- /* redo messages */
- XDrawImageString(display, win, gc,
- OFFSET_SPEED, font_height*2, stage_name,
- strlen(stage_name));
- if (score_incr>1) {
- sprintf(str,"Bonus x%d",score_incr);
- XDrawImageString(display, win, gc,
- OFFSET_SCORE, font_height*2, str,
- strlen(str));
- }
- print_balls();
- print_score();
- show_speeds();
- timer_active=TRUE;
- move_balls();
- break;
-
- case Button2:
- draw_pallet(); /* erase old */
- pallet_y = (double) (pallet_yI = PALLET_MAX_Y+4);
- pallet_row = MAX_ROW - 1;
- draw_pallet(); /* draw new */
- break;
-
- case Button1:
- draw_pallet(); /* erase old */
- if (pallet_yI > PALLET_MIN_Y) {
- old_pallet_y = pallet_y;
- pallet_y = (double) (pallet_yI -=16);
- pallet_row--;
-
- /* See if the ball could have been
- deflected as the pallete moved
- upwards */
- check_deflections(old_pallet_y);
- }
- draw_pallet(); /* draw new */
- break;
- }
- break;
-
- case KeyPress:
- XLookupString((XKeyEvent*) &e,keystr,2, NULL, NULL);
- if (keystr[0]==27) { /* Escape to save */
- if (!ball1.quadrant && !ball2.quadrant &&
- !ball3.quadrant && last_busted_brick==NULL) {
- XDrawImageString(display, win, gc,
- OFFSET_BALLS, font_height,
- "Saving... ",
- 23);
- save();
- }
- else
- XDrawImageString(display, win, gc,
- OFFSET_BALLS, font_height,
- "Not Saved... ",
- 23);
- }
- break;
-
- case MotionNotify:
- draw_pallet(); /* erase old pallet */
- pallet_x = (double) (pallet_xI =e.xmotion.x);
- mouse_yI = e.xmotion.y;
- draw_pallet(); /* draw new one */
- break;
-
- case EnterNotify:
- window_active = TRUE;
- break;
-
- case LeaveNotify:
- window_active = FALSE;
- break;
-
- case Expose:
- /* redraw the stage */
-
- for ( row = 0; row <= MAX_ROW; row++ ) {
- draw_brick0( row, 0 );
- for ( col = 1; col < MAX_COL; col++ )
- draw_brick( row, col );
- draw_brick0( row, MAX_COL );
- }
- draw_pallet();
- break;
-
- default:
- printf("unknown event: %d\n",e.type);
- break;
- }
- #ifdef INTR_DRAW
- XFlush(display);
- sigrelse(SIGALRM);
- #endif /*INTR_DRAW*/
- }
- }
- }
-
-
- void get_playground( argc, argv )
- int argc;
- char *argv[];
- {
- DIR *dirp;
- struct dirent *dp;
- struct stat st;
- int len, found;
-
- /* set default playground directory */
- strcpy( playground, STAGEDIR );
- strcat( playground, "/" );
- /* check for additional arguments (specific playground) */
- if ( argc > 1 ) {
- if ( argv[1][0] == '-' ) {
- /* list available playgrounds */
- printf( "available playgrounds are:\n" );
- printf( "\tdefault\n" );
- dirp = opendir(STAGEDIR);
- for( dp=readdir( dirp ); dp!=NULL; dp=readdir( dirp ) ) {
- if ( !strncmp( dp->d_name, "STAGES.", 7 ) )
- printf( "\t%s\n", (dp->d_name)+7 );
- }
- closedir( dirp );
- exit( 0 );
- }
- /* it's a playground name or private directory */
- if( !strcmp( argv[1], "default" ) ) {
- /* just in case someone used default */
- strcat( playground, "STAGES" );
- return;
- }
- found = 0;
- len = strlen( argv[1] );
- dirp = opendir( STAGEDIR );
- for( dp=readdir( dirp ); dp!=NULL; dp=readdir( dirp ) ) {
- if ( dp->d_reclen == len+7 &&
- !strcmp( (dp->d_name)+7, argv[1] ) ) {
- found++;
- break;
- }
- }
- closedir( dirp );
- if ( found )
- strcat( playground, dp->d_name );
- else {
- /* private dir */
- strcpy( playground, argv[1] );
- stat( playground, &st );
- if( !(st.st_mode & S_IFDIR) ) {
- printf( "private playground <%s> not a directory.\n",
- playground );
- exit( 1 );
- }
- }
- } else {
- strcat( playground, "STAGES" );
- }
- }
-
-
- /*** xblockbuster ***/
- void main( argc, argv )
- int argc;
- char *argv[];
-
- {
- XGCValues xgcvalues;
- Pixmap icon_image;
- XSizeHints size_hints;
- XWMHints wm_hints;
- XClassHint class_hints;
- XTextProperty VersionTextProp;
- static char *VersionList[2] = { VERSION, 0 };
-
- /* who am i ? ['cuserid(3S)' is fooled by 'su(1)'] */
- login = getpwuid( getuid( ) )->pw_name;
-
- if ((display=XOpenDisplay(NULL))==NULL) {
- fprintf(stderr, "Unable to open display: %s\n",
- XDisplayName(NULL));
- exit(1);
- }
- //(void) XSynchronize(display, 1); // For DEBUGGING
- screen_num = DefaultScreen(display);
- win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
- 0, 0, STAGE_WIDTH_IN_PIXELS, STAGE_HEIGHT_IN_PIXELS,
- 0, 2, WhitePixel(display, screen_num));
-
-
- XSelectInput(display, win, ExposureMask | ButtonPressMask |
- LeaveWindowMask | EnterWindowMask | KeyPressMask |
- PointerMotionMask);
-
-
- if ((font_info = XLoadQueryFont(display, FONT))==NULL) {
- fprintf(stderr,"Unable to load font %s\n",FONT);
- exit(1);
- }
- font_width= font_info->max_bounds.rbearing - font_info->min_bounds.lbearing;
- font_height=font_info->max_bounds.ascent + font_info->max_bounds.descent +1;
-
-
- xgcvalues.foreground = BlackPixel(display, screen_num);
- xgcvalues.background = WhitePixel(display, screen_num);
- xgcvalues.graphics_exposures = False;
- xgcvalues.font = font_info->fid;
-
- /* create the various graphic contexts we need. gc and gc_color
- differ only in the we only change the colors on the gc_color context,
- and thus, it is only used for brick drawing. gc_color really has no
- use on a black & white system */
-
- gc = XCreateGC(display, win, GCFont |
- GCForeground | GCBackground | GCGraphicsExposures, &xgcvalues);
- gc_color = XCreateGC(display, win, GCFont |
- GCForeground | GCBackground | GCGraphicsExposures, &xgcvalues);
-
- xgcvalues.function = GXclear;
- gc_erase = XCreateGC(display, win, GCForeground | GCBackground |
- GCFont | GCGraphicsExposures | GCFunction, &xgcvalues);
-
- xgcvalues.function = GXxor; /* Exclusive or */
- xgcvalues.foreground = WhitePixel(display, screen_num);
- xgcvalues.background = BlackPixel(display, screen_num);
-
- gc_xor = XCreateGC(display, win, GCForeground | GCBackground |
- GCFont | GCGraphicsExposures | GCFunction, &xgcvalues);
-
-
- /* Create our icon for when the window is closed */
-
- if (!(icon_image = XCreateBitmapFromData(display, win,
- blockbuster_bits,blockbuster_width, blockbuster_height)))
- {
- fprintf(stderr, "Can't create icon pixmap\n");
- exit (1);
- }
-
- size_hints.flags = PMinSize;
- size_hints.x = 0;
- size_hints.y = 0;
- size_hints.height = STAGE_HEIGHT_IN_PIXELS;
- size_hints.min_height = STAGE_HEIGHT_IN_PIXELS;
- size_hints.width = STAGE_WIDTH_IN_PIXELS;
- size_hints.min_width = STAGE_WIDTH_IN_PIXELS;
-
- wm_hints.flags = InputHint | IconPixmapHint;
- wm_hints.input = True;
- wm_hints.icon_pixmap = icon_image;
-
- class_hints.res_name = "XBlockbuster";
- class_hints.res_class = "XBlockbuster";
-
- XStringListToTextProperty(VersionList, 1, &VersionTextProp);
- XSetWMProperties(display, win, &VersionTextProp, &VersionTextProp,
- argv,argc, &size_hints, &wm_hints, &class_hints);
-
-
- XMapWindow(display, win);
- /* initialize random (used to determine next stage_nb) */
- srand48( time( 0 ) );
-
- get_playground( argc, argv );
-
- /* and off we go */
- bricks_init();
- ball_init();
- start_up( );
- ball1.quadrant = ball2.quadrant = ball3.quadrant = 0;
-
- event_handler();
- }
-